<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Forms\PersonnelForm;
use App\Http\Forms\RoleForm;
use App\Modules\Shop\Shop;
use App\Modules\User\Models\Admin;
use App\Modules\User\Manager;
use App\Http\Export\AdminExport;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Ramsey\Uuid\Uuid;
use Silber\Bouncer\BouncerFacade;
use Silber\Bouncer\Database\Role;
use Silber\Bouncer\Database\AssignedRole;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Support\Facades\DB;

class PersonnelController extends Controller
{
    public function index(Request $request)
    {
        $this->authorize("personnel");
        $search = $request->input('search', '');
        $searchShop = $request->input('searchShop', '');
        $export = $request->input('export', 0);

        $query = Admin::query()
                ->where('id', '!=', 1)
                ->when(!empty($searchShop), function ($query) use ($searchShop) {
                    $query->whereExists(function ($q) use ($searchShop) {
                        return $q->select(DB::raw(1))
                            ->from('shops')
                            ->whereRaw("(JSON_CONTAINS(admins.shop_id, JSON_ARRAY(shops.id)) OR JSON_CONTAINS(admins.shop_id, JSON_UNQUOTE(JSON_ARRAY(CONCAT(shops.id))))) AND (name like '%{$searchShop}%')");
                    });
                });

        if (!empty($search)) {
            $query->where(function ($q) use ($search) {
                return $q->where('admins.username', 'like', "%" . $search . "%")
                    ->orWhere('admins.name', 'like', "%" . $search . "%");
            });
        }
        $allShops = Shop::query()->get()->keyBy('id');
        if ($export) {
            $data = $query
                ->selectRaw('admins.*')
                ->get()
                ->map(function ($item) use ($allShops) {
                    $shopName = "";

                    $arr = json_decode($item->shop_id, true);
                    if (!empty($arr)) {
                        foreach ($arr as $value) {
                            $shop = $allShops->get($value);
                            if (!is_null($shop)) {
                                $shopName .= "," . $shop->name;
                            }
                        }
                    }
                    return [
                        $item->name,
                        $item->username,
                        $item->is_merchant_staff == 1 ? "是" : "否",
                        ltrim($shopName, ","),
                    ];
                });
            return (new AdminExport("工作人员.xlsx", $data->all()))->downLoad();
        }
        $count = $query->selectRaw('admins.*')->count();

        // $data = Admin::query()
        //     ->where('id', '!=', 1)
        //     ->orderBy('sort', 'desc')
        //     // ->orderBy('created_at', 'desc')
        //     ->paginate(20);
        $data = $query->orderBy('sort', 'desc')->orderBy('created_at', 'desc')->paginate(20);
        foreach ($data as $value) {
            $name = $value->getRoles()->toArray();
            $role = Role::query()->whereIn('name', $name)->get()->pluck('title')->all();
            $value->role = implode(",", $role);
        }
        $allShops = Shop::query()->get()->keyBy('id');
        $sidebar = "admin";
        return view('personnel.index', compact('data', 'sidebar', 'allShops', 'search', 'searchShop', 'count'));
    }

    public function create(Request $request)
    {
        $this->authorize("personnel-add");
        $shop = Shop::query()->get();
        $form = $this->form(PersonnelForm::class, [
            'method' => 'PUT',
            'url' => route('admin.personnel.store'),
        ], [
            'shop' => $shop->pluck('name', 'id')->all(),
        ]);
        $sidebar = "admin";
        $flag = 'personnel';
        return view('personnel.form', compact('form', 'sidebar', 'flag'));
    }

    public function store()
    {
        $form = $this->form(PersonnelForm::class);
        if (!$form->isValid()) {
            return redirect()->back()->withErrors($form->getErrors())->withInput();
        }
        $data = $form->getFieldValues();

        if (Admin::query()->where('username', $data['username'])->first()) {
            return redirect()->back()->withErrors("该用户名已存在");
        }

        $data['password']    = bcrypt('a12345678');
        $data['is_disabled'] = $data['is_disabled'] ?? 0;
        $data['is_clerk']    = 1;
        $data['shop_id']     = empty($data['shop_id']) ? '[]' : json_encode($data['shop_id']);
        $admin = Admin::query()->create($data);
        foreach ($data['role'] as $key => $value) {
            if ($value == 1) {
                BouncerFacade::assign($key)->to($admin);
            }
        }

        return redirect()->route('admin.personnel.index');
    }

    public function edit($id)
    {
        $admin = Admin::query()->find($id);
        $admin->shop_id = json_decode($admin->shop_id, true);
        $allRoles = $admin->getRoles()->toArray();
        $shop = Shop::query()->get();
        $form = $this->form(PersonnelForm::class, [
            'method' => 'POST',
            'url' => route('admin.personnel.update', ['id' => $id]),
            'model' => $admin,
        ], [
            'role' => $allRoles,
            'shop' => $shop->pluck('name', 'id')->all(),
        ]);
        $sidebar = "admin";
        $flag = 'personnel';
        return view('personnel.form', compact('form', 'sidebar', 'flag'));
        // $admin = Admin::query()->find($id);
        // $allRoles = $admin->getRoles()->toArray();
        // $shop = Shop::query()->get();
        // $form = $this->form(PersonnelForm::class, [
        //     'method' => 'POST',
        //     'url' => route('admin.personnel.update', ['id' => $id]),
        //     'model' => $admin,
        // ], [
        //     'role' => $allRoles,
        //     'shop' => $shop->pluck('name', 'id')->all(),
        // ]);
        // $sidebar = 'admin';
        // return view('personnel.form', compact('form', 'sidebar'));
    }

    public function update($id)
    {
        $form = $this->form(PersonnelForm::class);
        if ($id == 1) {
            return redirect()->back()->withErrors("您没有权限修改");
        }
        if (!$form->isValid()) {
            return redirect()->back()->withErrors($form->getErrors())->withInput();
        }
        $data = $form->getFieldValues();

        if (Admin::query()->where('username', $data['username'])->where('id', '<>', $id)->first()) {
            return redirect()->back()->withErrors("该用户名已存在");
        }

        if ($data['is_merchant_staff'] == 0) $data['shop_id'] = [];
        $admin = Admin::query()
            ->where('id', $id)
            ->first();
        $data['is_disabled'] = $data['is_disabled'] ?? 0;
        $data['is_clerk'] = 1;
        $admin->update($data);
        $role = [];
        foreach ($data['role'] as $key => $value) {
            if ($value == 1) {
                $role[] = $key;
            }
        }
        $allRoles = $admin->getRoles()->toArray();
        foreach (array_diff($allRoles, $role) as $value) {
            if (!is_null($value)) {
                BouncerFacade::retract($value)->from($admin);
            }
        }
        foreach (array_diff($role, $allRoles) as $value) {
            if (!is_null($value)) {
                BouncerFacade::assign($value)->to($admin);
            }
        }
        return redirect()->route('admin.personnel.index');
    }

    /**
     * 充值密码
     */
    public function resetpwd(Request $request){
        $this->authorize("personnel_resetpwd");

        $id = $request->input('account_id');

        if (empty($id)) {
            return redirect()->back()->withErrors('参数有误！');
        }

        $admin = Admin::query()->find($id);

        $admin->password = bcrypt('a12345678');

        $admin->setRememberToken(Str::random(60));

        $admin->save();

        event(new PasswordReset($admin));

        return redirect()->route('admin.personnel.index')->with('success', "重置密码成功，密码为：a12345678");
    }

    public function disable($id)
    {
        if ($id == 1) {
            return redirect()->back()->withErrors("您没有权限修改");
        }
        $admin = Admin::query()
            ->where('id', $id)
            ->first();
        $admin->is_disabled = $admin->is_disabled ? 0 : 1;
        $admin->save();
        return redirect()->route('admin.personnel.index');
    }

    public function role()
    {
        $this->authorize('authority');
        $data = BouncerFacade::role()
            ->where('name', '!=', 'superadmin')
            ->get();
        $sidebar = "role";
        return view('authority.role', compact('data', 'sidebar'));
    }

    public function createRole()
    {
        $this->authorize('authority-edit');
        $form = $this->form(RoleForm::class, [
            'method' => 'PUT',
            'url' => route('admin.authority.role.add'),
        ]);
        $sidebar = "role";
        $flag = "role";
        return view('authority.form', compact('form', 'sidebar', 'flag'));
    }

    public function addRole()
    {
        $this->authorize('authority-edit');
        $form = $this->form(RoleForm::class);
        if (!$form->isValid()) {
            return redirect()->back()->withErrors($form->getErrors())->withInput();
        }
        $data = $form->getFieldValues();
        BouncerFacade::role()->Create([
            'name' => Uuid::uuid4()->getHex(),
            'title' => $data['title'],
        ]);
        return redirect()->route('admin.authority.role');
    }

    public function editRole($id)
    {
        $this->authorize('authority-edit');
        $role = BouncerFacade::role()->where('id', $id)->first();
        $form = $this->form(RoleForm::class, [
            'method' => 'POST',
            'url' => route('admin.authority.role.update', ['id' => $id]),
            'model' => $role,
        ]);
        $sidebar = "role";
        $flag = "role";
        return view('authority.form', compact('form', 'sidebar', 'flag'));
    }

    public function updateRole($id)
    {
        $this->authorize('authority-edit');
        $form = $this->form(RoleForm::class);
        if (!$form->isValid()) {
            return redirect()->back()->withErrors($form->getErrors())->withInput();
        }
        $data = $form->getFieldValues();
        BouncerFacade::role()
            ->where('id', $id)
            ->update($data);
        BouncerFacade::refresh();
        return redirect()->route('admin.authority.role');
    }

    public function ability($role)
    {
        $this->authorize('authority-ability');
        $data = Role::query()->where('name', $role)->first()->getAbilities()->pluck('name')->all();
        $sidebar = "role";

        return view('authority.ability', compact('data', 'abilities', 'role', 'sidebar'));
    }

    public function allowAbility(Request $request, $role)
    {
        $this->authorize('authority-ability');
        $ability = $request->input('ability');
        foreach ($ability as $item) {
            BouncerFacade::allow($role)->to($item);
        }

        return response()->json([]);
    }

    public function disallowAbility(Request $request, $role)
    {
        $this->authorize('authority-ability');
        $ability = $request->input('ability');
        foreach ($ability as $item) {
            BouncerFacade::disallow($role)->to($item);
        }

        return response()->json([]);
    }

    /**
     * 修改排序
     */
    public function changeSort(Request $request)
    {
        $this->authorize('personnel');
        $id = $request->input('id');
        $sort = $request->input('sort');
        Admin::query()
            ->where('id', $id)
            ->update(['sort' => $sort]);
        return null;
    }

    /**
     * 删除用户
     */
    public function delete(Request $request)
    {
        $this->authorize('personnel_del');
        $id = $request->input('user_id');
        $admin = Admin::query()->find($id);
        $admin->delete();
        // return redirect()->back();
        return redirect()->route('admin.personnel.index')->with('success', "删除成功");
    }

    public function exportPartner(Request $request)
    {

        $search = $request->input('search');
        $searchReferrer = $request->input('searchReferrer');
        $level = $request->input('level');
        $file = (new PartnerExport("名单.xlsx"))->instance();
        $this->authorize("user-level{$level}-export");
        User::query()
            ->leftJoin('users as b', 'users.referrer_id', '=', 'b.id')
            ->leftJoin('users as c', 'users.personal_id', '=', 'c.id')
            ->when(!empty($level), function ($query) use ($level) {
                return $query->where('users.level', $level);
            })
            ->when(!is_null($level), function ($query) use ($level) {
                return $query->where('users.level', $level);
            })
            ->when(!empty($searchReferrer), function ($query) use ($searchReferrer) {
                return $query->where('c.name', $searchReferrer);
            })
            ->when(!empty($search), function ($query) use ($search) {
                return $query->where('users.nickname', 'like', "%" . $search . "%")
                    ->orWhere('users.mobile', 'like', "%" . $search . "%")
                    ->orWhere('users.name', 'like', "%" . $search . "%");
            })
            ->orderBy('users.created_at', 'desc')
            ->select("users.*", "b.name as referrer_name", "b.level as referrer_level", "c.name as personal_name")
            ->chunk(500, function ($item) use ($file) {
                $tmp = $item->map(function ($item2) {
                    $nickname = "";
                    $pattern = '/[\x{4e00}-\x{9fa5}a-zA-Z0-9_]/u';
                    preg_match_all($pattern, $item2->nickname, $nickname);
                    $nickname = join('', $nickname[0]);
                    return [
                        $item2->name,
                        $nickname,
                        $item2->mobile,
                        $item2->referrer_name,
                        User::$levelShow[$item2->referrer_level] ?? "",
                        $item2->created_at,
                        $item2->last_time,
                        $item2->personal_name,
                    ];
                });
                $file->addData($tmp->all());
            });
        return $file->downLoad();
    }
}
